package com.yifushidai.config;

//import com.tencent.xinge.XingeApp;

import com.yifushidai.entity.*;
import com.yifushidai.mapper.*;
import com.yifushidai.service.IcBindService;
import com.yifushidai.task.AsyncTask;
import com.yifushidai.utils.CustomPackUtils;
import com.yifushidai.utils.DateUtils;
import com.yifushidai.utils.JPushUtils;
import com.yifushidai.utils.ShisuMinaPushUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.mina.core.service.IoHandler;
import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.core.session.IoSession;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;

import java.text.ParseException;
import java.util.Date;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

public class ShisuIoHandler implements IoHandler {
    private Logger logger = LoggerFactory.getLogger(ShisuIoHandler.class);

    @Value("${shisu.mina.idle}")
    private int MINA_IDLE;

    public static ConcurrentHashMap<String, IoSession> sessionsConcurrentHashMap = new ConcurrentHashMap<String, IoSession>();//线程安全  服务端推送至硬件端用

    @Autowired
    private TokenEntityMapper tokenEntityMapper;
    @Autowired
    private ApiUniqueMacMapper apiUniqueMacMapper;
    @Autowired
    private OpenRecordEntityMapper openRecordMapper;
    @Autowired
    private KeypassBandEntityMapper keyPassMapper;
    @Autowired
    private IcBindService icBindService;
    @Autowired
    private OptDeviceLogMapper optDeviceLogMapper;
    @Autowired
    private AsyncTask asyncTask;

    @Override
    public void sessionCreated(IoSession ioSession) throws Exception {
        String remoteAddressAndSocket = ioSession.getRemoteAddress().toString();//192.168.1.3:55813
        ioSession.setAttribute("remoteAddressAndSocket", remoteAddressAndSocket);
        // 此处不应该：设置IoSession闲置时间，参数单位是秒
        // ioSession.getConfig().setIdleTime(IdleStatus.BOTH_IDLE, 10);
    }

    @Override
    public void sessionOpened(IoSession ioSession) throws Exception {
    }

    @Override
    public void sessionIdle(IoSession ioSession, IdleStatus idleStatus) {
        String uniqueMac = (String) ioSession.getAttribute("UniqueMac");
        String powerMac = (String) ioSession.getAttribute("PowerMac");
        String remoteAddressAndSocket = (String) ioSession.getAttribute("remoteAddressAndSocket");
        boolean uniqueFlag = StringUtils.isNotBlank(uniqueMac) && uniqueMac.matches("^\\w{24}$");
        boolean powerFlag = StringUtils.isNotBlank(powerMac) && powerMac.matches("^\\w{24}$");
//        logger.error("xxx {}：{}({}_{})", idleStatus, remoteAddressAndSocket, uniqueMac, powerMac);
        if (uniqueFlag) {
            ApiUniqueMac one = apiUniqueMacMapper.selectOne(ApiUniqueMac.builder().mac(uniqueMac).build());
            if (one != null) {
                if (!powerFlag) {//uniqueMac通道
                    optDeviceLogMapper.insertSelective(OptDeviceLog.builder().addressSocket(remoteAddressAndSocket).mobile(one.getMobile()).uniqueMac(uniqueMac).alias(one.getAddr() + one.getAlias()).optDesc("联网设备通道闲置").optTime(new Date(new Date().getTime() - 1000 * MINA_IDLE)).build());
                } else {//powerMac通道
                    optDeviceLogMapper.insertSelective(OptDeviceLog.builder().addressSocket(remoteAddressAndSocket).mobile(one.getMobile()).uniqueMac(uniqueMac).powerMac(powerMac).alias(one.getAddr() + one.getAlias()).optDesc("控电设备通道闲置").optTime(new Date(new Date().getTime() - 1000 * MINA_IDLE)).build());
                }
            }
        }
        ioSession.closeNow();//重连
    }

    @Override
    public void exceptionCaught(IoSession ioSession, Throwable throwable) {
        String uniqueMac = (String) ioSession.getAttribute("UniqueMac");
        String powerMac = (String) ioSession.getAttribute("PowerMac");
        boolean uniqueFlag = StringUtils.isNotBlank(uniqueMac) && uniqueMac.matches("^\\w{24}$");
        boolean powerFlag = StringUtils.isNotBlank(powerMac) && powerMac.matches("^\\w{24}$");
        String remoteAddressAndSocket = (String) ioSession.getAttribute("remoteAddressAndSocket");
//        logger.error("xxx exceptionCaught：{}({}_{})\n{}\n{}", remoteAddressAndSocket, uniqueMac, powerMac, throwable.getMessage(), throwable);
        if (uniqueFlag) {
            ApiUniqueMac one = apiUniqueMacMapper.selectOne(ApiUniqueMac.builder().mac(uniqueMac).build());
            if (one != null) {
                if (!powerFlag) {//uniqueMac通道
                    optDeviceLogMapper.insertSelective(OptDeviceLog.builder().addressSocket(remoteAddressAndSocket).mobile(one.getMobile()).uniqueMac(uniqueMac).alias(one.getAddr() + one.getAlias()).optDesc("联网设备通道异常" + throwable).build());
                } else {//powerMac通道
                    optDeviceLogMapper.insertSelective(OptDeviceLog.builder().addressSocket(remoteAddressAndSocket).mobile(one.getMobile()).uniqueMac(uniqueMac).powerMac(powerMac).alias(one.getAddr() + one.getAlias()).optDesc("控电设备通道异常" + throwable).build());
                }
            }
        }
        ioSession.closeNow();//重连
    }

    @Override
    public void sessionClosed(IoSession ioSession) throws ParseException {
        String uniqueMac = (String) ioSession.getAttribute("UniqueMac");
        String powerMac = (String) ioSession.getAttribute("PowerMac");
        String remoteAddressAndSocket = (String) ioSession.getAttribute("remoteAddressAndSocket");
        boolean uniqueFlag = StringUtils.isNotBlank(uniqueMac) && uniqueMac.matches("^\\w{24}$");
        boolean powerFlag = StringUtils.isNotBlank(powerMac) && powerMac.matches("^\\w{24}$");
        logger.error("xxx sessionClosed：{}({}_{})", remoteAddressAndSocket, uniqueMac, powerMac);
        if (uniqueFlag) {
            ApiUniqueMac one = apiUniqueMacMapper.selectOne(ApiUniqueMac.builder().mac(uniqueMac).build());
            if (null == one) return;
            if (!powerFlag) {//uniqueMac通道
                one.setLs(CustomPackUtils.OFF_LINE);
                //通道一心跳(离线) >>> 通道二重连(在线，map更新) >>> 通道一闲置(离线，map移除) >>> 通道二心跳(在线，map移除，无法推送)
//                sessionsConcurrentHashMap.remove(uniqueMac);//IoSession关闭前处理：map移除当前ioSession，更新离线状态，释放连接
//                optDeviceLogMapper.insertSelective(OptDeviceLog.builder().addressSocket(remoteAddressAndSocket).mobile(one.getMobile()).uniqueMac(uniqueMac).alias(one.getAddr() + one.getAlias()).optDesc("联网设备通道关闭").build());
            } else {//powerMac通道
                one.setPowerStatus(CustomPackUtils.OFF_LINE);
                //通道一心跳(离线) >>> 通道二重连(在线，map更新) >>> 通道一闲置(离线，map移除) >>> 通道二心跳(在线，map移除，无法推送)
//                sessionsConcurrentHashMap.remove(powerMac);//IoSession关闭前处理：map移除当前ioSession，更新离线状态，释放连接
//                optDeviceLogMapper.insertSelective(OptDeviceLog.builder().addressSocket(remoteAddressAndSocket).mobile(one.getMobile()).uniqueMac(uniqueMac).powerMac(powerMac).alias(one.getAddr() + one.getAlias()).optDesc("控电设备通道关闭").build());
            }
            apiUniqueMacMapper.updateByPrimaryKey(one);
        }
    }

    @Override
    public void messageReceived(IoSession ioSession, Object o) throws Exception {
        String uniqueMac = (String) ioSession.getAttribute("UniqueMac");
        String powerMac = (String) ioSession.getAttribute("PowerMac");
        String remoteAddressAndSocket = (String) ioSession.getAttribute("remoteAddressAndSocket");
        String message = o.toString().trim();
        logger.warn("<<< 硬件端：{}({}_{}) 参数：{}", remoteAddressAndSocket, uniqueMac, powerMac, message);
        if (StringUtils.isBlank(message) || !message.matches("^\\w+:\\w+$")) {
            return;//重试
        }
        String[] msg = message.split(":");
        String head = msg[0];
        String body = msg[1];

        //初始化请求过滤
        if ("UniqueMac".equals(head)) {
            if (!body.matches("^\\w{24}$")) return;//重试
            uniqueMac = body.toUpperCase();
        } else if ("PowerMacBind".equals(head)) {
            if (!body.matches("^\\w{24}_\\w{24}$")) return;//重试
            uniqueMac = body.toUpperCase().split("_")[0];
            powerMac = body.toUpperCase().split("_")[1];
        }
        boolean uniqueFlag = StringUtils.isNotBlank(uniqueMac) && uniqueMac.matches("^\\w{24}$");
        if (!uniqueFlag) {//非初始化请求从ioSession中取mac，为空则重连
            ioSession.closeNow();//重连
            return;
        }
        StringBuilder param = new StringBuilder();
        ApiUniqueMac one = apiUniqueMacMapper.selectOne(ApiUniqueMac.builder().mac(uniqueMac).build());
        if (null == one) {
            return;//重试
        } else {
            param.append("老板！").append(one.getAlias()).append("房间于").append(DateUtils.getCurrent2());
        }

        //业务处理
        switch (head) {
            case "SessionClosed"://1.0. 蓝牙配对，联网设备Mac断开重连，主动发送SessionClosed                格式：SessionClosed:0
                ioSession.closeNow();//重连
                return;

            case "UniqueMac"://1.1 联网设备Mac在线，首次连接或每次断开重连，新建ioSession UniqueMac:${__CSVRead(G:\mac.csv,2)}            格式：UniqueMac:uniqueMac
                macInit(ioSession, uniqueMac, powerMac, remoteAddressAndSocket, one, param);
                return;

            case "LockMacBind"://1.2. 锁mac绑定                格式：LockMacBind:lockMac
                if (!body.matches("^\\w{24}$")) return;//重试
                if (StringUtils.isNotBlank(one.getLockMac())) return;//重试
                lockMacBind(ioSession, uniqueMac, powerMac, remoteAddressAndSocket, message, body, one, param);
                return;

            case "LockOpen"://1.3. 开门结果 + 推送（IC卡开门失败锁端不请求）                格式：LockOpen:type_result
                if (!body.matches("^\\w{2,5}_\\w{1}$")) return;//重试
                lockOpen(ioSession, uniqueMac, powerMac, remoteAddressAndSocket, body, one, param);
                return;

            case "LockPower"://1.4. 门锁电量提醒 + 推送                格式：LockPower:pl/pf 电量低/电量正常
                if (!body.matches("^\\w{2}$")) return;//重试
                lockPower(ioSession, uniqueMac, powerMac, remoteAddressAndSocket, body, one, param);
                return;

            case "CardMacBind"://1.5. 插卡设备mac绑定                格式：CardMacBind:cardMac
                if (!body.matches("^\\w{24}$")) return;//重试
                if (StringUtils.isNotBlank(one.getCardMac())) return;//重试
                cardMacBind(ioSession, uniqueMac, powerMac, remoteAddressAndSocket, message, body, one, param);
                return;

            case "CardStatus"://1.6. 插卡设备状态（含电量提醒 + 推送 消息转发，至控电模块）                格式：CardStatus:on/of_pl/pf
                if (!body.matches("^\\w{2}_\\w{2}$")) return;//重试
                cardStatus(ioSession, uniqueMac, powerMac, remoteAddressAndSocket, message, body, one, param);
                return;

            case "PowerMacBind"://1.7. 控电设备mac绑定（WIFI模块）                格式：PowerMacBind:uniqueMac_powerMac
                if (StringUtils.isNotBlank(one.getPowerMac()) && !one.getPowerMac().equals(powerMac)) return;//重试
                powerMacBind(ioSession, uniqueMac, powerMac, remoteAddressAndSocket, one, param);
                return;

            case "MinaPush"://2.0 在messageReceived()方法，收到返回消息即刻唤醒                格式： MinaPush:OK
                boolean powerFlag = StringUtils.isNotBlank(powerMac) && powerMac.matches("^\\w{24}$");
                ResultLock resultLock = ShisuMinaPushUtils.lockMap.get(powerFlag ? powerMac : uniqueMac);
                if (resultLock != null) {
                    synchronized (resultLock) {
                        resultLock.notify();
                        resultLock.setMessage(body);//结果值
                    }
                }
                return;

            default:
                logger.warn("<<< 硬件端：非法协议{}", message);
        }
    }

    private void powerMacBind(IoSession ioSession, String uniqueMac, String powerMac, String remoteAddressAndSocket, ApiUniqueMac one, StringBuilder param) {
        if (powerMac.equals(one.getPowerMac())) {
            try {
                one.setPowerStatus(CustomPackUtils.ON_LINE);
                apiUniqueMacMapper.updateByPrimaryKeySelective(one);

                ioSession.setAttribute("UniqueMac", uniqueMac);// 添加mac 到当前ioSession，心跳维持
                ioSession.setAttribute("PowerMac", powerMac);// 添加mac 到当前ioSession，心跳维持
                sessionsConcurrentHashMap.put(powerMac, ioSession);// 添加当前ioSession 到静态集合 服务端推送至硬件端用

                ioSession.write(CustomPackUtils.SUCCESS_HEX_CMD);
                logger.info(">>> 硬件端：{}({}_{}) 参数：{}", remoteAddressAndSocket, uniqueMac, powerMac, CustomPackUtils.SUCCESS_HEX_CMD);

                optDeviceLogMapper.insertSelective(OptDeviceLog.builder().addressSocket(remoteAddressAndSocket).mobile(one.getMobile()).uniqueMac(uniqueMac).powerMac(powerMac).alias(one.getAddr() + one.getAlias()).optDesc("控电设备重连").build());
            } catch (Exception e) {
                optDeviceLogMapper.insertSelective(OptDeviceLog.builder().addressSocket(remoteAddressAndSocket).mobile(one.getMobile()).uniqueMac(uniqueMac).powerMac(powerMac).alias(one.getAddr() + one.getAlias()).optDesc("控电设备激活异常！" + e.getMessage()).build());
            }
        } else if (null == apiUniqueMacMapper.selectOne(ApiUniqueMac.builder().powerMac(powerMac).build())) {
            try {
                one.setPowerMac(powerMac);
                one.setPowerStatus(CustomPackUtils.ON_LINE);
                apiUniqueMacMapper.updateByPrimaryKeySelective(one);

                ioSession.setAttribute("UniqueMac", uniqueMac);// 添加mac 到当前ioSession，心跳维持
                ioSession.setAttribute("PowerMac", powerMac);// 添加mac 到当前ioSession，心跳维持
                sessionsConcurrentHashMap.put(powerMac, ioSession);// 添加当前ioSession 到静态集合 服务端推送至硬件端用

                ioSession.write(CustomPackUtils.SUCCESS_HEX_CMD);
                logger.info(">>> 硬件端：{}({}_{}) 参数：{}", remoteAddressAndSocket, uniqueMac, powerMac, CustomPackUtils.SUCCESS_HEX_CMD);

                Set<String> mobileSet = new LinkedHashSet<>();
                mobileSet.add(one.getMobile());
                mobileSet.add(one.getMobile2());
                JPushUtils.shisuNotification(tokenEntityMapper, mobileSet, param.append("控电设备激活成功！").toString(), JPushUtils.OTHER_NOTIFICATION_TYPE);
                optDeviceLogMapper.insertSelective(OptDeviceLog.builder().addressSocket(remoteAddressAndSocket).mobile(one.getMobile()).uniqueMac(uniqueMac).powerMac(powerMac).alias(one.getAddr() + one.getAlias()).optDesc(param.toString()).build());
            } catch (Exception e) {
                optDeviceLogMapper.insertSelective(OptDeviceLog.builder().addressSocket(remoteAddressAndSocket).mobile(one.getMobile()).uniqueMac(uniqueMac).powerMac(powerMac).alias(one.getAddr() + one.getAlias()).optDesc("控电设备激活异常！" + e.getMessage()).build());
            }
        } else {
            optDeviceLogMapper.insertSelective(OptDeviceLog.builder().addressSocket(remoteAddressAndSocket).mobile(one.getMobile()).uniqueMac(uniqueMac).powerMac(powerMac).alias(one.getAddr() + one.getAlias()).optDesc("控电设备重复激活").build());
        }
    }

    private void cardStatus(IoSession ioSession, String uniqueMac, String powerMac, String remoteAddressAndSocket, String message, String body, ApiUniqueMac one, StringBuilder param) {
        String status = body.split("_")[0];
        String power = body.split("_")[1];

        if ("pf".equalsIgnoreCase(power)) {
            one.setCales(CustomPackUtils.ON_LINE);
        } else {
            one.setCales(CustomPackUtils.OFF_LINE);

            Set<String> mobileSet = new LinkedHashSet<>();
            mobileSet.add(one.getMobile());
            mobileSet.add(one.getMobile2());
            JPushUtils.shisuNotification(tokenEntityMapper, mobileSet, param.append("插卡设备电量低！请及时更换电池！").toString(), JPushUtils.OTHER_NOTIFICATION_TYPE);
            optDeviceLogMapper.insertSelective(OptDeviceLog.builder().addressSocket(remoteAddressAndSocket).mobile(one.getMobile()).uniqueMac(uniqueMac).alias(one.getAddr() + one.getAlias()).optDesc(param.toString()).build());
        }
        apiUniqueMacMapper.updateByPrimaryKeySelective(one);

        //2.9. 控电设备来断电控制（来自插卡设备的消息转发）                格式：powerControl:on/of
        if ("on".equalsIgnoreCase(status)) {//异步任务：即时取电
            ioSession.write(message);//即时取电：转发前回复，否则硬件未收到回复会一直重发；转发失败推送管理员手机
            logger.info(">>> 硬件端：{}({}_{}) 参数：{}", remoteAddressAndSocket, uniqueMac, powerMac, message);
            optDeviceLogMapper.insertSelective(OptDeviceLog.builder().addressSocket(remoteAddressAndSocket).mobile(one.getMobile()).uniqueMac(uniqueMac).alias(one.getAddr() + one.getAlias()).optDesc("插卡").build());

            asyncTask.nowPushPowerOn(one, remoteAddressAndSocket);//异步任务

        } else {//异步任务：延时断电
            ioSession.write(message);//延时断电：转发前回复，否则延时断电期间硬件未收到回复会一直重发；转发失败推送管理员手机
            logger.info(">>> 硬件端：{}({}_{}) 参数：{}", remoteAddressAndSocket, uniqueMac, powerMac, message);
            optDeviceLogMapper.insertSelective(OptDeviceLog.builder().addressSocket(remoteAddressAndSocket).mobile(one.getMobile()).uniqueMac(uniqueMac).alias(one.getAddr() + one.getAlias()).optDesc("拔卡").build());

            asyncTask.delayPushPowerOf(one, remoteAddressAndSocket);//异步任务

        }
    }

    private void cardMacBind(IoSession ioSession, String uniqueMac, String powerMac, String remoteAddressAndSocket, String message, String body, ApiUniqueMac one, StringBuilder param) {
        try {
            one.setCardMac(body);
            apiUniqueMacMapper.updateByPrimaryKeySelective(one);

            ioSession.write(message);//数据原样返回，硬件绑定处理
            logger.info(">>> 硬件端：{}({}_{}) 参数：{}", remoteAddressAndSocket, uniqueMac, powerMac, message);

            Set<String> mobileSet = new LinkedHashSet<>();
            mobileSet.add(one.getMobile());
            mobileSet.add(one.getMobile2());
            JPushUtils.shisuNotification(tokenEntityMapper, mobileSet, param.append("插卡设备激活成功！").toString(), JPushUtils.OTHER_NOTIFICATION_TYPE);
            optDeviceLogMapper.insertSelective(OptDeviceLog.builder().addressSocket(remoteAddressAndSocket).mobile(one.getMobile()).uniqueMac(uniqueMac).alias(one.getAddr() + one.getAlias()).optDesc(param.toString()).build());
        } catch (Exception e) {
            optDeviceLogMapper.insertSelective(OptDeviceLog.builder().addressSocket(remoteAddressAndSocket).mobile(one.getMobile()).uniqueMac(uniqueMac).alias(one.getAddr() + one.getAlias()).optDesc("插卡设备激活异常！" + e.getMessage()).build());
        }
    }

    private void lockPower(IoSession ioSession, String uniqueMac, String powerMac, String remoteAddressAndSocket, String body, ApiUniqueMac one, StringBuilder param) {
        if ("pf".equalsIgnoreCase(body)) {
            one.setLes(CustomPackUtils.ON_LINE);
        } else {
            one.setLes(CustomPackUtils.OFF_LINE);

            Set<String> mobileSet = new LinkedHashSet<>();
            mobileSet.add(one.getMobile());
            mobileSet.add(one.getMobile2());
            JPushUtils.shisuNotification(tokenEntityMapper, mobileSet, param.append("门锁电量低！请及时更换电池！").toString(), JPushUtils.OTHER_NOTIFICATION_TYPE);
            optDeviceLogMapper.insertSelective(OptDeviceLog.builder().addressSocket(remoteAddressAndSocket).mobile(one.getMobile()).uniqueMac(uniqueMac).alias(one.getAddr() + one.getAlias()).optDesc(param.toString()).build());
        }
        apiUniqueMacMapper.updateByPrimaryKeySelective(one);

        ioSession.write(CustomPackUtils.SUCCESS_HEX_CMD);
        logger.info(">>> 硬件端：{}({}_{}) 参数：{}", remoteAddressAndSocket, uniqueMac, powerMac, CustomPackUtils.SUCCESS_HEX_CMD);
    }

    private void lockOpen(IoSession ioSession, String uniqueMac, String powerMac, String remoteAddressAndSocket, String body, ApiUniqueMac one, StringBuilder param) {
        String type = body.split("_")[0];
        int result = Integer.valueOf(body.split("_")[1]);

        KeypassBandEntity keyPass = keyPassMapper.queryByMac(one.getMac());
        String mark = "";
        if ("TK".equals(type)) {
            mark = keyPass.getTempkey();
            if (keyPass.getUpdateTime().getTime() > new Date().getTime()) {//临时密码未失效
                asyncTask.lockOpenPushTempKey(one, keyPass.getTempkey(), ioSession, remoteAddressAndSocket);
            }
        }
        if ("FK".equals(type)) {
            mark = keyPass.getKeypass();
        }
        if (type.startsWith("C")) {
            IcBind record = new IcBind();
            record.setMac(one.getMac());
            record.setIcType(type.substring(1, 2));
            List<IcBind> list = icBindService.selectByMacAndIcType(record);
            mark = list.get(0).getIcId();
        }

        //插入开门记录
        if (0 == result) {
            param.append("开门成功-").append(type).append(" ").append(mark);
        } else {
            param.append("开门失败");
        }
        //插入开门记录
        openRecordMapper.insertSelective(OpenRecordEntity.builder().mac(one.getMac()).result(result).typ(type).mark(mark).build());

        Set<String> mobileSet = new LinkedHashSet<>();
        mobileSet.add(one.getMobile());
        mobileSet.add(one.getMobile2());
        JPushUtils.shisuNotification(tokenEntityMapper, mobileSet, param.toString(), JPushUtils.LOG_LOCK_OPEN_NOTIFICATION_TYPE);
        optDeviceLogMapper.insertSelective(OptDeviceLog.builder().addressSocket(remoteAddressAndSocket).mobile(one.getMobile()).uniqueMac(uniqueMac).alias(one.getAddr() + one.getAlias()).optDesc(param.toString()).build());

        ioSession.write(CustomPackUtils.SUCCESS_HEX_CMD);
        logger.info(">>> 硬件端：{}({}_{}) 参数：{}", remoteAddressAndSocket, uniqueMac, powerMac, CustomPackUtils.SUCCESS_HEX_CMD);

        //3分钟四次报警
//        if (result == 1) {
//            Date openTime = new Date();
//            Date lastTime = DateUtils.subTime(180000L, openTime);
//            Map<String, Object> map = new LinkedHashMap<>();
//            map.put("openTime", openTime);//当前失败时间
//            map.put("lastTime", lastTime); //3分钟之前  上限时间
//            map.put("mac", one.getMac());
//            List<OpenRecordEntity> failOpenRecordList = openRecordMapper.queryWarnList(map);
//            int count = 0;
//            if (failOpenRecordList.size() >= 4) {
//                for (OpenRecordEntity failOpenRecord : failOpenRecordList) {
//                    if (failOpenRecord.getResult() == 1) {
//                        count++;
//                        if (count == 4) {
//                            //推送。。。。。
//                            JPushUtils.shisuNotification(one.getMobile(), "尊敬的房东您好，" + one.getAlias() + "号房间三分钟内已连续四次开门失败，请及时关注是否为恶意开门！", "安全提醒");
//                            break;
//                        }
//                    } else {
//                        count = 0;
//                    }
//                }
//            }
//        }
    }

    private void lockMacBind(IoSession ioSession, String uniqueMac, String powerMac, String remoteAddressAndSocket, String message, String body, ApiUniqueMac one, StringBuilder param) {
        try {
            one.setLockMac(body);
            apiUniqueMacMapper.updateByPrimaryKeySelective(one);

            ioSession.write(message);//数据原样返回，硬件绑定处理
            logger.info(">>> 硬件端：{}({}_{}) 参数：{}", remoteAddressAndSocket, uniqueMac, powerMac, message);

            Set<String> mobileSet = new LinkedHashSet<>();
            mobileSet.add(one.getMobile());
            mobileSet.add(one.getMobile2());
            JPushUtils.shisuNotification(tokenEntityMapper, mobileSet, param.append("门锁激活成功！").toString(), JPushUtils.OTHER_NOTIFICATION_TYPE);
            optDeviceLogMapper.insertSelective(OptDeviceLog.builder().addressSocket(remoteAddressAndSocket).mobile(one.getMobile()).uniqueMac(uniqueMac).alias(one.getAddr() + one.getAlias()).optDesc(param.toString()).build());
        } catch (Exception e) {
            optDeviceLogMapper.insertSelective(OptDeviceLog.builder().addressSocket(remoteAddressAndSocket).mobile(one.getMobile()).uniqueMac(uniqueMac).alias(one.getAddr() + one.getAlias()).optDesc("门锁激活异常！" + e.getMessage()).build());
        }
    }

    private void macInit(IoSession ioSession, String uniqueMac, String powerMac, String remoteAddressAndSocket, ApiUniqueMac one, StringBuilder param) throws InterruptedException {
        if (CustomPackUtils.OFF_LINE == one.getLs()) {
            one.setLs(CustomPackUtils.ON_LINE);
            apiUniqueMacMapper.updateByPrimaryKeySelective(one);
        }
        ioSession.setAttribute("UniqueMac", uniqueMac);// 添加mac 到当前ioSession，心跳维持
        sessionsConcurrentHashMap.put(uniqueMac, ioSession);// 添加当前ioSession 到静态集合 服务端推送至硬件端用

        //应答
        ioSession.write(CustomPackUtils.SUCCESS_HEX_CMD);
        logger.info(">>> 硬件端：{}({}_{}) 参数：{}", remoteAddressAndSocket, uniqueMac, powerMac, CustomPackUtils.SUCCESS_HEX_CMD);

        if (CustomPackUtils.OFF_LINE == one.getInitFlag()) {
            Thread.sleep(3000);

            //解绑门锁MAC
            ioSession.write("lockMacUnbind:NA");
            logger.info(">>> 硬件端：{}({}_{}) 参数：{}", remoteAddressAndSocket, uniqueMac, powerMac, "lockMacUnbind:NA");

            Thread.sleep(1000);

            //解绑插卡MAC
            ioSession.write("cardMacUnbind:NA");
            logger.info(">>> 硬件端：{}({}_{}) 参数：{}", remoteAddressAndSocket, uniqueMac, powerMac, "cardMacUnbind:NA");

            one.setInitFlag(CustomPackUtils.ON_LINE);
            apiUniqueMacMapper.updateByPrimaryKeySelective(one);

            Set<String> mobileSet = new LinkedHashSet<>();
            mobileSet.add(one.getMobile());
            mobileSet.add(one.getMobile2());
            JPushUtils.shisuNotification(tokenEntityMapper, mobileSet, param.append("联网设备初始化成功！").toString(), JPushUtils.OTHER_NOTIFICATION_TYPE);
            optDeviceLogMapper.insertSelective(OptDeviceLog.builder().addressSocket(remoteAddressAndSocket).mobile(one.getMobile()).uniqueMac(uniqueMac).alias(one.getAddr() + one.getAlias()).optDesc(param.toString()).build());
        } else {
            optDeviceLogMapper.insertSelective(OptDeviceLog.builder().addressSocket(remoteAddressAndSocket).mobile(one.getMobile()).uniqueMac(uniqueMac).alias(one.getAddr() + one.getAlias()).optDesc("联网设备重连").build());
        }
    }

    @Override
    public void messageSent(IoSession ioSession, Object o) throws Exception {
    }

    @Override
    public void inputClosed(IoSession ioSession) throws Exception {
    }

//    /* XinGe 推送：通知*/
//    public void sendXinGeNotice(String mac, String content, String title) {
//        BandLockEntity lock = lockMapper.queryByMac(mac);
//        String alias = lock.getAlias();
//        String mb = lock.getMobile();
//        String xingeToken = xingeMapper.selectByPrimaryKey(mb).getXingeToken();
//        String appType = userMapper.selectByMobile(mb).getApptype();
//        boolean flag = XinGeUtils.pushByTokenAndApptype(appType, alias, xingeToken, content, title, XingeApp.IOSENV_PROD);
//        if (flag) {
//            logger.info(">>> XinGe通知成功：{} 参数：{}", mb, content);
//        } else {
//            logger.info(">>> XinGe通知失败：{} 参数：{}", mb, content);
//        }
//    }
//
//    /* XinGe 推送：透传*/
//    public void sendXinGeMessage(String mac, String content) {
//        BandLockEntity lock = lockMapper.queryByMac(mac);
//        String mb = lock.getMobile();
//        String xingeToken = xingeMapper.selectByPrimaryKey(mb).getXingeToken();
//        String appType = userMapper.selectByMobile(mb).getApptype();
//        boolean flag = XinGeUtils.pushMessage(appType, xingeToken, content);
//        if (flag) {
//            logger.info(">>> XinGe透传成功：{} 参数：{}", mb, content);
//        } else {
//            logger.info(">>> XinGe透传失败：{} 参数：{}", mb, content);
//        }
//    }

}